package com.sunmouse.toollib.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import java.util.Timer;
import java.util.TimerTask;


/**
 * Created by Kvin on 2017/1/19.
 */
public class SimpleWebView extends WebView {
    private final String error_page = "file:///android_asset/error.html";
    public final int ERROR_TIME_OUT = 1;
    private ProgressBar mProgress;//loading progress
    private Context mContext;

    private Handler mHandler;
    private Timer mTimer;
    private final int TIME_OUT = 15;//15 seconds

    private boolean isTimeOutChecked;
    private OnProgressChangedListener mListener;

    public SimpleWebView(Context context) {
        super(context);
        init(context);
    }


    public SimpleWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SimpleWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public SimpleWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }


    /**
     * confi setting info
     *
     * @param context
     */
    private void init(Context context) {
        setTimeOutChecked(true);

        mHandler = new WebHandler();
        this.mContext = context;
        mProgress = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
        mProgress.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 10, 0, 0));
        mProgress.setMax(100);
        addView(mProgress);
        //handle issues
        setWebChromeClient(new SimpleWebChromeClient());
        setWebViewClient(new SimpleWebViewClient());
        //set some attrs
        getSettings().setJavaScriptEnabled(true);
        getSettings().setRenderPriority(WebSettings.RenderPriority.NORMAL);
        getSettings().setEnableSmoothTransition(true);
        getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //设置 缓存模式
        getSettings().setDomStorageEnabled(true);
        getSettings().setDatabaseEnabled(true);

        setZoomDpi(context);

        //getSettings().setLoadsImagesAutomatically(false);//whether loading images

        setClickable(false);
        setFocusable(false);
    }


    /**
     * release timer
     */
    private void releaseTimer() {
        if (isTimeOutChecked) {
            if (mTimer != null) {
                mTimer.cancel();
                mTimer = null;
            }
        }
    }

    /**
     * timer switch
     *
     * @param timeOutChecked
     */
    public void setTimeOutChecked(boolean timeOutChecked) {
        isTimeOutChecked = timeOutChecked;
    }

    /**
     * set zoom density dpi
     * combine using setUseWideViewPort and setLoadWithOverviewMode    then the web page include content
     * and border fits the screen by width
     *
     * @param context
     */
    private void setZoomDpi(Context context) {
        getSettings().setSupportZoom(true);
//        getSettings().setBuiltInZoomControls(true);
        getSettings().setUseWideViewPort(true);
        getSettings().setLoadWithOverviewMode(true);
//        getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
    }


    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_STAR) {
            return super.dispatchKeyEvent(event);
        }
        return false;
    }

    /**
     * web view client :handle some loading issues or errors
     */
    private class SimpleWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//            LogUtils.e("--------------shouldOverrideUrlLoading  " + view.getUrl());
            return true;//handle mUrl itself
//            return super.shouldOverrideUrlLoading(view, request);
        }

//


        @Override
        public void onLoadResource(WebView view, String url) {
            //you can filter some ads,images or other content here
//            LogUtils.d("--------------onLoadResource  " + mUrl);
//            if (mUrl.contains(Media.Type.PNG) || mUrl.contains(Media.Type.JPG) || mUrl.contains(Media.Type.JPEG)) {
//                mUrl = mLocalImage;
//                view.loadUrl(mUrl);
////                return;
//            }
//            if (mUrl.contains(".js")) return;
            super.onLoadResource(view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
//            LogUtils.e("--------------onPageStarted  " + mUrl);
            if (mProgress.getVisibility() != VISIBLE) {
                mProgress.setVisibility(View.VISIBLE);
            }
            startTimer();
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            //will be invoked whenever the page changes
//            LogUtils.e("--------------onPageFinished  " + mUrl + "  progress=" + view.getmProgress());
            releaseTimer();
            super.onPageFinished(view, url);
        }


        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            super.onReceivedError(view, request, error);
            if (mProgress.getVisibility() == View.VISIBLE)
                mProgress.setVisibility(View.GONE);

            //loading custom error html eg;
            view.loadUrl(error_page);
        }

    }

    /**
     * launch timer{use for counting time out}
     */
    private void startTimer() {
        if (isTimeOutChecked) {
            mTimer = new Timer();
            mTimer.schedule(new TimeOutTask(), TIME_OUT * 1000, 1000);
        }
    }

    /**
     * read time out
     */
    private class TimeOutTask extends TimerTask {
        @Override
        public void run() {
            mHandler.sendEmptyMessage(0);
        }
    }


    /**
     * web client:use for adding progress bar
     */
    private class SimpleWebChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
//            LogUtils.d("----Progress="+newProgress);
            if (mProgress.getVisibility() != View.VISIBLE) {
                mProgress.setVisibility(View.VISIBLE);
            }
            mProgress.setProgress(newProgress);
            if (mListener != null) mListener.onProgressChanged(newProgress);
            if (newProgress == 100) {
                mProgress.setVisibility(View.GONE);
                releaseTimer();
            }
        }

        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            return super.onConsoleMessage(consoleMessage);
        }
    }

    /**
     * webview handler
     */
    private class WebHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                if (mProgress.getProgress() < 100) {
                    loadUrl(error_page);

                    releaseTimer();
                }
            }
        }
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        LayoutParams lp = (LayoutParams) mProgress.getLayoutParams();
        lp.x = l;
        lp.y = t;
        mProgress.setLayoutParams(lp);
        super.onScrollChanged(l, t, oldl, oldt);
    }

    /**
     * set cathe directory
     */
    public void setCatheDirctory(String path) {
        getSettings().setAppCacheEnabled(true);
        getSettings().setAppCachePath(path);
    }

//    @Override
//    protected void onSizeChanged(int w, int h, int ow, int oh) {
//        super.onSizeChanged(w, h, ow, oh);
//        LogUtils.d("-------------w=" + w + " :h=" + h);
//    }
//
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
////        DisplayMetrics metrics=getResources().getDisplayMetrics();
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//    }


//    @Override
//    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        super.onLayout(changed, l, t, r, b);
//        int count = getChildCount();
//        if (count > 0) {
//            for (int i = 0; i < count; i++) {
//                getChildAt(i).setBackgroundResource(R.color.red);
////                getChildAt(i).setFocusable(false);
//            }
//        }
//        LogUtils.d("--------count=" + count);
//    }

    public void setOnProgressChangedListener(OnProgressChangedListener mListener) {
        this.mListener = mListener;
    }

    /**
     * progress
     */
    public interface OnProgressChangedListener {
        void onProgressChanged(int progress);
    }
}
